package com.ouc.common.ncRead;


import com.ouc.common.constant.VariableName;
import com.ouc.common.entity.*;
import org.springframework.lang.Nullable;
import ucar.ma2.InvalidRangeException;
import ucar.nc2.NetcdfFile;
import ucar.nc2.Variable;

import java.io.IOException;
import java.text.ParseException;
import java.util.Date;
import java.util.List;
import java.util.Map;


public interface NcDao {

  /**
   * 获取变量的方法
   * 传输的变量名与真实的nc文件中的变量名不一定匹配；通过variableName枚举类遍历枚举，获得真实变量名，进而获得变量
   *
   * @param file         nc文件
   * @param variableName 变量名
   * @return 变量
   */
  @Nullable
  Variable getVariable(NetcdfFile file, String variableName) throws IOException;


  /**
   * 获取变量的方法
   * 确定变量的枚举类型，加快查找变量的速度
   * 传输的变量名与真实的nc文件中的变量名不一定匹配；通过variableName枚举类遍历枚举，获得真实变量名，进而获得变量
   *
   * @param file         nc文件
   * @param variableName 变量枚举类型
   * @return 变量
   */
  @Nullable
  Variable getVariable(NetcdfFile file, VariableName variableName) throws IOException;

  /**
   * 获取 nc 格网数据。默认 0 层数据
   *
   * @param file         nc文件
   * @param variableName 变量名
   * @return 返回nc格网数据
   * @throws IOException
   * @throws InvalidRangeException
   */
  NcGridData getNcGridData(NetcdfFile file, String variableName) throws IOException, InvalidRangeException;

  /**
   * 获取 nc 格网数据
   *
   * @param file         nc文件
   * @param variableName 变量名
   * @param depth        深度层级
   * @return 返回nc格网数据
   * @throws IOException
   * @throws InvalidRangeException
   */
  NcGridData getNcGridData(NetcdfFile file, String variableName, @Nullable Integer depth) throws IOException, InvalidRangeException;

  /**
   * 获取 nc 格网数据（有限制条件）。默认 0 层
   *
   * @param file         nc文件
   * @param variableName 变量名
   * @param lon          经度限制条件
   * @param lat          纬度限制条件
   * @return 返回nc格网数据
   * @throws IOException
   * @throws InvalidRangeException
   */
  NcGridData getNcGridData(NetcdfFile file, String variableName, @Nullable Float[] lon, @Nullable Float[] lat) throws IOException, InvalidRangeException;

  /**
   * 获取 nc 格网数据（有限制条件）。
   *
   * @param file         nc文件
   * @param variableName 变量名
   * @param lon          经度限制条件
   * @param lat          纬度限制条件
   * @param depth        深度层级
   * @return 返回nc格网数据
   * @throws IOException
   * @throws InvalidRangeException
   */
  NcGridData getNcGridData(NetcdfFile file, String variableName, @Nullable Float[] lon, @Nullable Float[] lat, @Nullable Integer depth) throws IOException, InvalidRangeException;

  /**
   * 获取 nc 格网数据（有限制条件）。
   *
   * @param file         nc文件
   * @param variableName 变量名
   * @param lon          经度
   * @param lat          纬度
   * @param positionOf0  第三个限制条件 （一般是深度）
   * @param positionOf1  第四个限制条件 （一般是时间）
   * @return
   * @throws IOException
   * @throws InvalidRangeException
   */
  NcGridData getNcGridData(NetcdfFile file, String variableName, @Nullable Float[] lon, @Nullable Float[] lat, @Nullable Integer positionOf0, Integer positionOf1) throws IOException, InvalidRangeException;

  /**
   * 获取文件中变量的全部数据，及其相关维度数据。对于 3 维及以上的数据，是切片的数据
   *
   * @param file         nc文件
   * @param variableName 变量名
   * @return 返回变量，及其相关维度的数组  如果是 3 维数据，取 0 维 0 层切片；如果是 4 维数据，取 0 维 0 层、 1 维 0 层切片；
   * @throws IOException
   * @throws InvalidRangeException
   */
  Map<String, NcData> getNcDataOfSlice(NetcdfFile file, String variableName) throws IOException, InvalidRangeException;

  /**
   * 获取文件中变量的全部数据，及其相关维度数据。对于 3 维及以上的数据，是切片的数据
   *
   * @param file         nc文件
   * @param variableName 变量名
   * @param positionOf0  如果是 3 维数据，该参数代表第 0 维切片层数；如果是 4 维数据，该参数代表第 1 维切片层数
   * @return 返回变量，及其相关维度的数组  如果是 3 维数据，取 0 维 positionOf0 层切片；如果是 4 维数据，取 0 维 0 层、1 维 positionOf0 层切片
   * @throws IOException
   * @throws InvalidRangeException
   */
  Map<String, NcData> getNcDataOfSlice(NetcdfFile file, String variableName, @Nullable Integer positionOf0) throws IOException, InvalidRangeException;

  /**
   * 获取文件中变量的全部数据，及其相关维度数据。对于 3 维及以上的数据，是切片的数据
   *
   * @param file         nc文件
   * @param variableName 变量名
   * @param positionOf0  如果是 3 维数据，该参数代表第 0 维切片层数；如果是 4 维数据，该参数代表第 1 维切片层数
   * @param positionOf1  如果是 3 维数据，不会使用该参数；如果是 4 维数据，该参数代表第 0 维切片层数
   * @return 返回变量，及其相关维度的数组  如果是 3 维数据，取 0 维 positionOf0 层切片；如果是 4 维数据，取 0 维 positionOf1 层、1 维 positionOf0 层切片
   * @throws IOException
   * @throws InvalidRangeException
   */
  Map<String, NcData> getNcDataOfSlice(NetcdfFile file, String variableName, @Nullable Integer positionOf0, @Nullable Integer positionOf1) throws IOException, InvalidRangeException;

  /**
   * 默认获取深度第0层，限制经纬度的单一变量数据
   *
   * @param file         nc文件
   * @param variableName 变量名
   * @param lon          [startLon,endLon]
   * @param lat          [startLat,endLat]
   * @return 返回限制经纬度的nc数据。
   */
  Map<String, NcData> getNcDataWithLimit(NetcdfFile file, String variableName, @Nullable Float[] lon, @Nullable Float[] lat) throws IOException, InvalidRangeException;

  /**
   * 默认获取深度第positionOf0层，限制经纬度的单一变量数据
   *
   * @param file         nc文件
   * @param variableName 变量名
   * @param lon          [startLon,endLon]
   * @param lat          [startLat,endLat]
   * @param positionOf0  深度第 positionOf0 层
   * @return 返回限制经纬度的nc数据。
   */
  Map<String, NcData> getNcDataWithLimit(NetcdfFile file, String variableName, @Nullable Float[] lon, @Nullable Float[] lat, @Nullable Integer positionOf0) throws IOException, InvalidRangeException;

  /**
   * 限制经纬度的单一变量数据
   *
   * @param file         nc文件
   * @param variableName 变量名
   * @param lon          经度
   * @param lat          纬度
   * @param positionOf0  第三个限制条件 （一般是深度）
   * @param positionOf1  第四个限制条件 （一般是时间）
   * @return
   * @throws IOException
   * @throws InvalidRangeException
   */
  Map<String, NcData> getNcDataWithLimit(NetcdfFile file, String variableName, @Nullable Float[] lon, @Nullable Float[] lat, @Nullable Integer positionOf0, Integer positionOf1) throws IOException, InvalidRangeException;

  /**
   * 获取限制经纬度，深度的单一变量数据
   *
   * @param file         nc文件
   * @param variableName 变量名
   * @param lon          [startLon,endLon]
   * @param lat          [startLat,endLat]
   * @param depth        [startDepth,endDepth]
   * @return 返回限制经纬度，深度的nc数据。
   */
  Map<String, NcData> getNcDataWithLimitByDepth(NetcdfFile file, String variableName, @Nullable Float[] lon, @Nullable Float[] lat, @Nullable Float[] depth) throws IOException, InvalidRangeException;

  /**
   * 获取限制经纬度，深度的单一变量数据
   *
   * @param file         nc文件
   * @param variableName 变量名
   * @param lon          [startLon,endLon]
   * @param lat          [startLat,endLat]
   * @param level        [startLevel,endLevel]
   * @return 返回限制经纬度，深度的nc数据。
   */
  Map<String, NcData> getNcDataWithLimitByLevel(NetcdfFile file, String variableName, @Nullable Float[] lon, @Nullable Float[] lat, @Nullable Integer[] level) throws IOException, InvalidRangeException;

  /**
   * 获取某一个值的经纬度深度信息
   *
   * @param ncFile       nc文件
   * @param key          传入值
   * @param variableName 变量名
   * @return List<NcIndex>
   * @throws IOException           文件不存在
   * @throws InvalidRangeException 数组越界
   */
  List<NcIndex> getIndex(NetcdfFile ncFile, float key, String variableName) throws IOException, InvalidRangeException;

  /**
   * 获取变量，因为只有文件
   * 所以如果多个变量无法判断到底想要哪一个变量
   * 所以使用此方法会得到除了lat，lon，time，depth的其他变量列表(排除一部分变量)
   *
   * @param file nc文件
   * @return 除了lat，lon，time，depth的其他变量列表
   * @throws IOException
   */
  @Nullable
  List<Variable> getVariableExclude(NetcdfFile file) throws IOException;

  /**
   * 对变量名进行重新命名，只用于存放数据库格式规范
   * 如果在这个方法中已经识别出来的是一种变量的会跟改名字
   * 否则不会，方便用于前台数据库检索
   *
   * @param originName 原始变量名
   * @return
   */
  String variableRename(String originName);

  /**
   * 对nc文件中的所有一维数据进行获取
   * map的键值对分别是variable.shortName()和对应的NcData
   * 一般是时间，经度，纬度，深度（深度如果有的话）
   * 具体使用，先获取map，再从map中获取键，键是ncDao.getVariable(ncFile,VariableName.UFLOW).getShortName()
   * 直接从map中get即可
   * 当然如果知道变量的shortName，直接get也行并且更快
   *
   * @param file nc文件
   * @return
   */
  Map<String, NcData> getNcDataOfOneDimensional(NetcdfFile file);

  /**
   * 通过nc文件获取里面所有变量的相关值
   * 一般来讲三维数据就是海表面高度，lat，lon，time
   * 四维数据就是跟深度有关的数据，lat，lon，time，depth
   * 三维数据，position0就是时间，position1不起作用
   * 四维数据position0就是深度，position1就是深度
   * 具体使用可以先获取map，再通过map找到键，从中再找到值
   * 键是shortName
   * 具体示范：Map<String, NcData> map = ncDao.getNcData(ncFile, 25, 25);
   * map.get(ncDao.getVariable(ncFile, VariableName.UFLOW).getShortName())
   * 当然如果知道变量的shortName，直接get也行并且更快
   *
   * @param ncFile      nc文件
   * @param positionOf0 参数1，如果是 3 维数据，该参数代表第 0 维切片层数就是时间；如果是 4 维数据，该参数代表第 1 维切片层数，一般是深度
   * @param positionOf1 如果是 3 维数据，不会使用该参数；如果是 4 维数据，该参数代表第 0 维切片层数，一般是时间
   * @return
   */
  Map<String, NcData> getNcData(NetcdfFile ncFile, Integer positionOf0, Integer positionOf1);

  /**
   * 通过nc文件获取里面所有变量的相关值
   * 一般来讲三维数据就是海表面高度，lat，lon，time
   * 四维数据就是跟深度有关的数据，lat，lon，time，depth
   * 三维数据，position0就是时间，position1不起作用
   * 四维数据position0就是深度，position1就是深度
   * 具体使用可以先获取map，再通过map找到键，从中再找到值
   * 键是shortName
   * 具体示范：Map<String, NcData> map = ncDao.getNcData(ncFile, 25, 25);
   * map.get(ncDao.getVariable(ncFile, VariableName.UFLOW).getShortName())
   * 当然如果知道变量的shortName，直接get也行并且更快
   *
   * @param ncFile      nc文件
   * @param positionOf0 如果是 3 维数据，该参数代表第 0 维切片层数就是时间；如果是 4 维数据，该参数代表第 1 维切片层数，一般是深度
   * @return
   */
  Map<String, NcData> getNcData(NetcdfFile ncFile, Integer positionOf0);

  /**
   * 通过nc文件获取里面所有变量的相关值
   * 一般来讲三维数据就是海表面高度，lat，lon，time
   * 四维数据就是跟深度有关的数据，lat，lon，time，depth
   * 返回变量，及其相关维度的数组  如果是 3 维数据，取 0 维 0 层切片；如果是 4 维数据，取 0 维 0 层、 1 维 0 层切片；
   * 就是指三维数据（已见过的nc文件只有海面高度），去掉时间，四维数据，去掉时间，只取深度第一层数据
   * 具体使用可以先获取map，再通过map找到键，从中再找到值
   * 键是shortName
   * 具体示范：Map<String, NcData> map = ncDao.getNcData(ncFile, 25, 25);
   * map.get(ncDao.getVariable(ncFile, VariableName.UFLOW).getShortName())
   * 当然如果知道变量的shortName，直接get也行并且更快
   *
   * @param ncFile nc文件
   * @return
   */
  Map<String, NcData> getNcData(NetcdfFile ncFile);

  /**
   * 获取nc文件限制经纬度的所有数据
   * 使用map<String,NcData>存储，String是变量的shortName
   *
   * @param ncFile nc文件
   * @param lon    经度限制条件
   * @param lat    纬度限制条件
   * @param depth  深度
   * @return
   */
  Map<String, NcData> getNcDataOfLimit(NetcdfFile ncFile, @Nullable Float[] lon, @Nullable Float[] lat, @Nullable Integer depth);

  /**
   * 获取nc文件限制经纬度的所有数据
   *
   * @param ncFile nc文件
   * @param lon    经度限制条件
   * @param lat    纬度限制条件
   * @param depth  深度
   * @param time   时间
   * @return
   */
  Map<String, NcData> getNcDataOfLimit(NetcdfFile ncFile, @Nullable Float[] lon, @Nullable Float[] lat, @Nullable Integer depth, Integer time);

  /**
   * 判断某个变量名是否在VariableName里面
   * 如果有返回true，否则返回false
   * 常用于判断是否属于经度，纬度，深度
   *
   * @param originName   需要判断的名字
   * @param variableName 想要和哪一个VariableName进行判断
   * @return
   */
  Boolean isContainVariableName(String originName, VariableName variableName);

  /**
   * 获取nc文件的深度对应map
   *
   * @param ncFile nc文件
   * @return
   * @throws IOException
   * @throws InvalidRangeException
   */
  Map<Integer, Float> getLevelMap(NetcdfFile ncFile) throws IOException, InvalidRangeException;

  /**
   * 获取和originName相同属性的variableName
   * 不需要打开nc文件去判断，而是通过循环判断可能会更快一点
   * variableNameList应该是各种变量名
   * originName应该是你想查找的变量名（同类型即可）
   * 例如list里面有salt，uo，vo，想查找和uu同类型的变量名
   * 就会查找到uo（不需要打开nc文件了）
   *
   * @param originName       给予的变量名
   * @param variableNameList nc文件的变量列表（只要包含给予的变量名的String的list集合）
   * @return list如果有给予的变量名同属性的变量返回此变量名，否则返回null
   */
  String getVariableName(String originName, List<String> variableNameList);

  /**
   * 获取nc补偿值
   * 因为nc文件是一个圆柱
   * cesium是一个球，因此对于中间跨过边界值时要进行补偿
   * 数组拼接
   *
   * @param ncFile   nc文件
   * @param lon      经度范围
   * @param lat      纬度范围
   * @param variable 变量
   * @param level    层级
   * @return
   * @throws IOException
   * @throws InvalidRangeException
   */
  NcCompensate getNcCompensate(NetcdfFile ncFile, Float[] lon, Float[] lat, Variable variable, Integer level) throws IOException, InvalidRangeException;

  /**
   * 获取nc补偿值
   * 因为nc文件是一个圆柱
   * cesium是一个球，因此对于中间跨过边界值时要进行补偿
   * 数组拼接
   *
   * @param ncFile   nc文件
   * @param lon      经度限制条件
   * @param lat      纬度限制条件
   * @param variable 变量
   * @param level    层级
   * @param time     时间
   * @return
   * @throws IOException
   * @throws InvalidRangeException
   */
  NcCompensate getNcCompensate(NetcdfFile ncFile, Float[] lon, Float[] lat, Variable variable, Integer level, Integer time) throws IOException, InvalidRangeException;

  /**
   * 获取nc文件某个变量的所有限制条件
   * 一般是经度纬度深度时间四维
   * 三维数据，position0就是时间，position1不起作用
   * 四维数据position0就是深度，position1就是深度
   *
   * @param ncFile       nc文件
   * @param variableName 变量名（同类型即可）
   * @param positionOf0  时间或者深度
   * @param positionOf1  时间或无
   * @return
   * @throws IOException
   * @throws InvalidRangeException
   */

  Map<String, NcData> getNcDataOfSliceFromVariable(NetcdfFile ncFile, String variableName, Integer positionOf0, Integer positionOf1) throws IOException, InvalidRangeException;

  /**
   * 获取nc文件某个变量的所有限制条件
   * 一般是经度纬度深度时间四维
   * 三维数据，position0就是时间，position1不起作用
   * 四维数据position0就是深度，position1就是深度
   *
   * @param ncFile       nc文件
   * @param variableName 变量名（同类型即可）
   * @param positionOf0  时间或者深度
   * @return
   * @throws IOException
   * @throws InvalidRangeException
   */
  Map<String, NcData> getNcDataOfSliceFromVariable(NetcdfFile ncFile, String variableName, Integer positionOf0) throws IOException, InvalidRangeException;

  /**
   * 获取nc文件某个变量的所有限制条件
   * 一般是经度纬度深度时间四维
   * 三维数据，position0就是时间，position1不起作用
   * 四维数据position0就是深度，position1就是深度
   *
   * @param ncFile       nc文件
   * @param variableName 变量名（同类型即可）
   * @return
   * @throws IOException
   * @throws InvalidRangeException
   */
  Map<String, NcData> getNcDataOfSliceFromVariable(NetcdfFile ncFile, String variableName) throws IOException, InvalidRangeException;

  /**
   * 获取nc文件中的数据
   * 从经纬度限制中获取数据
   *
   * @param ncFile       nc文件
   * @param variableName 变量名
   * @param lon          经度限制条件 如果传null认为经度没有限制
   * @param lat          纬度限制条件 如果传null认为纬度没有限制
   * @param positionOf0  倒数第三维限制条件
   * @param positionOf1  倒数第四维限制条件
   * @return
   * @throws IOException
   * @throws InvalidRangeException
   */
  Map<String, NcData> getNcDataOfLimitFromVariable(NetcdfFile ncFile, String variableName, Float[] lon, Float[] lat, Integer positionOf0, Integer positionOf1) throws IOException, InvalidRangeException;

  /**
   * 获取nc文件中的数据
   * 从经纬度限制中获取数据
   *
   * @param ncFile       nc文件
   * @param variableName 变量名
   * @param lon          经度限制条件 如果传null认为经度没有限制
   * @param lat          纬度限制条件 如果传null认为纬度没有限制
   * @param positionOf0  倒数第三维限制条件
   * @return
   * @throws IOException
   * @throws InvalidRangeException
   */
  Map<String, NcData> getNcDataOfLimitFromVariable(NetcdfFile ncFile, String variableName, Float[] lon, Float[] lat, Integer positionOf0) throws IOException, InvalidRangeException;

  /**
   * 获取限制经纬度的数据
   * （默认三维，取第三维一层，四维取第三维一层，第四维一层）
   *
   * @param ncFile       nc文件
   * @param variableName 变量名
   * @param lon          经度限制条件
   * @param lat          纬度限制条件
   * @return
   * @throws IOException
   * @throws InvalidRangeException
   */
  Map<String, NcData> getNcDataOfLimitFromVariable(NetcdfFile ncFile, String variableName, Float[] lon, Float[] lat) throws IOException, InvalidRangeException;

  /**
   * 绘制粒子流相关方法
   *
   * @param value        二维数组
   * @param lonArr       经度数组
   * @param latArr       纬度数组
   * @param dilution     稀释倍数
   * @param exaggerate   夸张倍数（为了粒子流好看）
   * @param variableName 是u还是v变量（两个不一样，除了这两个传其他的返回空）
   * @return
   */
  FlowData getParticleFlowData(float[][] value, float[] lonArr, float[] latArr, int dilution, int exaggerate, VariableName variableName, boolean reverseFlag, boolean startByZero);

  /**
   * 绘制风场粒子流相关方法
   *
   * @param value        二维数组
   * @param lonArr       经度数组
   * @param latArr       纬度数组
   * @param dilution     稀释倍数
   * @param exaggerate   夸张倍数（为了粒子流好看）
   * @param variableName 是u还是v变量（两个不一样，除了这两个传其他的返回空）
   * @return
   */
  FlowData getParticleFlowDataWithWind(float[][] value, float[] lonArr, float[] latArr, int dilution, int exaggerate, VariableName variableName);

  /**
   * 只用来获取所有层的数据
   * 是一个立方体
   * 这应该是一个三维数据
   *
   * @param ncFile       nc文件
   * @param variableName 变量民
   * @param lon          经度
   * @param lat          纬度
   * @return
   * @throws IOException
   * @throws InvalidRangeException
   */
  NcRecord getData3DWithLimit(NetcdfFile ncFile, String variableName, Float[] lon, Float[] lat) throws IOException, InvalidRangeException;

  /**
   * 只用来获取所有层的数据
   * 是一个立方体
   * 这应该是一个三维数据
   *
   * @param ncFile       nc文件
   * @param variableName 变量名
   * @param lon          经度限制条件
   * @param lat          纬度限制条件
   * @param positionOf0  第0维限制条件
   * @return
   * @throws IOException
   * @throws InvalidRangeException
   */
  NcRecord getData3DWithLimit(NetcdfFile ncFile, String variableName, Float[] lon, Float[] lat, Integer positionOf0) throws IOException, InvalidRangeException;

  /**
   * 获取nc文件的时间属性
   *
   * @param ncFile nc文件
   * @return
   * @throws IOException
   * @throws InvalidRangeException
   * @throws ParseException
   */
  String getNcTime(NetcdfFile ncFile) throws IOException, InvalidRangeException, ParseException;

  /**
   * 获取nc文件的时间属性
   * 适用于time不一样的情况
   * 得到一个时间数据集合
   *
   * @param ncFile nc文件
   * @return 返回时间的集合
   * @throws IOException
   * @throws InvalidRangeException
   * @throws ParseException
   */
  List<String> getNcTimeForList(NetcdfFile ncFile) throws IOException, InvalidRangeException, ParseException;

  /**
   * 限制循环次数
   * 获取nc文件开始索引和结束索引之间的时间字符串集合
   *
   * @param ncFile     nc文件
   * @param startIndex 开始索引
   * @param endIndex   结束索引
   * @return
   * @throws IOException
   * @throws InvalidRangeException
   * @throws ParseException
   */
  List<String> getNcTimeForList(NetcdfFile ncFile, int startIndex, int endIndex) throws IOException, InvalidRangeException, ParseException;

  /**
   * 通过nc文件和时间换算获取时间的索引
   * date是nc文件的time数组的第几个
   * 从0开始，（pet涡旋数据集使用的话应该是需要两个索引一年的开始和结束
   * 例如想要2019年的，应该写成获取2019-01-01的索引和2020-01-01的索引，然后做循环）
   * 另外针对pet的nc数据集异常值加了49710
   *
   * @param ncFile nc文件
   * @param date   日期
   * @return 时间对应索引
   * @throws IOException
   * @throws InvalidRangeException
   */
  Integer getNcTimeIndex(NetcdfFile ncFile, Date date) throws IOException, InvalidRangeException;

  /**
   * 获取nc文件
   *
   * @param filePath nc文件路径
   * @return
   * @throws IOException
   * @throws InvalidRangeException
   */
  NetcdfFile getNcFile(String filePath) throws IOException, InvalidRangeException;

  /**
   * 获取文件的深度数组
   *
   * @param ncFile nc文件
   * @return
   */
  float[] getLevel(NetcdfFile ncFile) throws IOException;

  /**
   * 获取nc文件上传需要的有关信息
   *
   * @param ncFile nc文件
   * @return
   * @throws IOException
   */
  NcUploadInfo getNcUploadInfo(NetcdfFile ncFile) throws IOException;

  /**
   * 获取文件的经纬度
   *
   * @param ncFile nc文件
   * @return map集合，键分别是lon和lat
   * @throws IOException
   * @throws InvalidRangeException
   */
  Map<String, NcData> getLonAndLat(NetcdfFile ncFile) throws IOException, InvalidRangeException;

  /**
   * 获取所有层的数据
   * 并不加经纬度的限制
   *
   * @param ncFile       nc文件
   * @param variableName 变量名
   * @return
   * @throws IOException
   * @throws InvalidRangeException
   */
  NcRecord getData3DOfVariables(NetcdfFile ncFile, String variableName) throws IOException, InvalidRangeException;

  /**
   * 获取某一条直线上的数据，通过差值的方法，
   *
   * @param ncFile       nc文件路径
   * @param variableName 变量名
   * @param startLat     开始纬度
   * @param startLon     开始经度
   * @param endLat       结束纬度
   * @param endLon       结束经度
   * @param position     层级
   * @param pointNum     直线上点的数目
   */
  Float[][] getDataLineOfVariable(NetcdfFile ncFile, Float startLat, Float startLon, Float endLat, Float endLon, String variableName, Integer position, Integer pointNum) throws IOException, InvalidRangeException;

  /**
   * 获取某个点的数据
   * @param ncFile nc文件路径
   * @param startLat 点的纬度
   * @param startLon 点的经度
   * @param variableName 变量名
   * @param position 层级
   * @return
   * @throws IOException
   * @throws InvalidRangeException
   */
  Float[][] getDataPointOfVariable(NetcdfFile ncFile, Float startLat, Float startLon, String variableName, Integer position) throws IOException, InvalidRangeException;
}
